﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Murray.MSMAPI
{
    public class SABnzbd
    {
        #region Properties

        public string BaseURL { get; set; }
        public string APIKey { get; set; }

        #endregion

        #region Constructors

        public SABnzbd()
        {
            CombineUrlAndApiKey();
        }

        public SABnzbd(string siteUrl, string apiKey)
        {
            BaseURL = siteUrl;
            APIKey = apiKey;

            CombineUrlAndApiKey();
        }

        #endregion

        #region Helper Methods

        private void CombineUrlAndApiKey()
        {
            if (!String.IsNullOrEmpty(BaseURL))
            {
                if (!String.IsNullOrEmpty(APIKey))
                {
                    UpdateSABnzbdUrl();
                    UpdateApiKey();
                }
                else
                {
                    throw new ArgumentNullException("ApiKey", "SABnzbd API Key cannot be null");
                }
            }
            else
            {
                throw new ArgumentNullException("BaseUrl", "SABnzbd Base Url cannot be null");
            }
        }

        private void UpdateApiKey()
        {
            BaseURL = BaseURL + "apikey=" + APIKey;
        }

        private void UpdateSABnzbdUrl()
        {
            if (!BaseURL.ToLower().EndsWith("/"))
            {
                if (!BaseURL.ToLower().EndsWith("sabnzbd"))
                {
                    BaseURL = BaseURL + "/sabnzbd/api?";
                }
                else
                {
                    BaseURL = BaseURL + "/api?";
                }
            }
            else
            {
                if (!BaseURL.ToLower().EndsWith("sabnzbd/"))
                {
                    BaseURL = BaseURL + "sabnzbd/api?";
                }
                else
                {
                    BaseURL = BaseURL + "api?";
                }
            }
        }

        private string CallWebService(Uri webServiceUri)
        {
            string webServiceResult;

            HttpWebRequest webServiceRequest = HttpWebRequest.CreateHttp(webServiceUri);
            using (HttpWebResponse webServiceResponse = (HttpWebResponse)webServiceRequest.GetResponse())
            {
                Stream webServiceStream = webServiceResponse.GetResponseStream();
                using (StreamReader webServiceReader = new StreamReader(webServiceStream))
                {
                    webServiceResult = webServiceReader.ReadToEnd();
                }
            }

            return webServiceResult;
        }

        #endregion

        #region Output

        public SABnzbdQueue QueueOutput()
        {
            SABnzbdQueue queueOutputResult = new SABnzbdQueue();

            Uri queueUri = new Uri(BaseURL + "&mode=queue&output=json");
            string queueJsonString = CallWebService(queueUri);
            JObject queueJsonObject = JObject.Parse(queueJsonString);

            queueOutputResult.active_lang = (string)queueJsonObject["queue"]["active_lang"];
            queueOutputResult.cache_art = (string)queueJsonObject["queue"]["cache_art"];
            queueOutputResult.cache_max = (string)queueJsonObject["queue"]["cache_max"];
            queueOutputResult.cache_size = (string)queueJsonObject["queue"]["cache_size"];

            List<SABnzbdCategory> listCategories = new List<SABnzbdCategory>();
            foreach (string currentCategory in queueJsonObject["queue"]["categories"].Values<string>())
            {
                SABnzbdCategory newCategory = new SABnzbdCategory();
                newCategory.category = currentCategory;
                listCategories.Add(newCategory);
            }

            queueOutputResult.categories = listCategories;
            queueOutputResult.color_scheme = (string)queueJsonObject["queue"]["color_scheme"];
            queueOutputResult.darwin = (bool)queueJsonObject["queue"]["darwin"];
            queueOutputResult.diskspace1 = (double)queueJsonObject["queue"]["diskspace1"];
            queueOutputResult.diskspace2 = (double)queueJsonObject["queue"]["diskspace2"];
            queueOutputResult.diskspacetotal1 = (double)queueJsonObject["queue"]["diskspacetotal1"];
            queueOutputResult.diskspacetotal2 = (double)queueJsonObject["queue"]["diskspacetotal2"];
            queueOutputResult.eta = (string)queueJsonObject["queue"]["eta"];
            queueOutputResult.finish = (int)queueJsonObject["queue"]["finish"];
            queueOutputResult.finishaction = (string)queueJsonObject["queue"]["finishaction"];
            queueOutputResult.have_quota = (bool)queueJsonObject["queue"]["have_quota"];
            queueOutputResult.have_warnings = (string)queueJsonObject["queue"]["have_warnings"];
            queueOutputResult.helpuri = (string)queueJsonObject["queue"]["helpuri"];
            queueOutputResult.isverbose = (bool)queueJsonObject["queue"]["isverbose"];
            queueOutputResult.kbpersec = (double)queueJsonObject["queue"]["kbpersec"];
            queueOutputResult.last_warning = (string)queueJsonObject["queue"]["last_warning"];
            queueOutputResult.left_quota = (string)queueJsonObject["queue"]["left_quota"];
            queueOutputResult.limit = (int)queueJsonObject["queue"]["limit"];
            queueOutputResult.loadavg = (string)queueJsonObject["queue"]["loadavg"];
            queueOutputResult.mb = (double)queueJsonObject["queue"]["mb"];
            queueOutputResult.mbleft = (double)queueJsonObject["queue"]["mbleft"];
            queueOutputResult.my_home = (string)queueJsonObject["queue"]["my_home"];
            queueOutputResult.my_lcldata = (string)queueJsonObject["queue"]["my_lcldata"];
            queueOutputResult.new_rel_url = (string)queueJsonObject["queue"]["new_rel_url"];
            queueOutputResult.new_release = (string)queueJsonObject["queue"]["new_release"];
            queueOutputResult.newzbin_url = (string)queueJsonObject["queue"]["newzbin_url"];
            queueOutputResult.noofslots = (int)queueJsonObject["queue"]["noofslots"];
            queueOutputResult.nt = (bool)queueJsonObject["queue"]["nt"];

            return queueOutputResult;
        }

        #endregion
    }
}
